﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.Composite.Events;
using BlueMarble.Genesis.Infrastructure.Interfaces;

namespace BlueMarble.Genesis.Security.Authentication
{
    public class AuthenticationViewModel : IAuthenticationViewModel, INotifyPropertyChanged
    {
        protected IEventAggregator eventAggregator;

        protected BlueMarble.Genesis.Infrastructure.Security.Authentication authentication;
        protected BlueMarble.Genesis.Infrastructure.Security.Membership membership;

        protected string username;
        protected string lastVerifiedUsername;
        protected bool isLoggedIn;
#if !SILVERLIGHT
        protected string[] userRoles;
#else
        protected System.Collections.ObjectModel.ObservableCollection<string> userRoles;
#endif
        protected string lastUserInRole;

        public AuthenticationViewModel(IEventAggregator eventAggregator)
        {
            username = string.Empty;
            lastVerifiedUsername = string.Empty;
            isLoggedIn = false;
            lastUserInRole = string.Empty;
            userRoles = null;

            this.eventAggregator = eventAggregator;

            authentication = new Infrastructure.Security.Authentication();
            membership = new Infrastructure.Security.Membership();

            authentication.LoginCompleted += new Infrastructure.Security.LoginEventHandler(authentication_LoginCompleted);
            authentication.LogoutCompleted += new Infrastructure.Security.LogoutEventHandler(authentication_LogoutCompleted);
            authentication.ValidUserCompleted += new Infrastructure.Security.ValidUserEventHandler(authentication_ValidUserCompleted);
            authentication.IsLoggedInCompleted += new Infrastructure.Security.IsLoggedInEventHandler(authentication_IsLoggedInCompleted);

            membership.GetRolesForCurrentUserCompleted += new Infrastructure.Security.GetRolesForCurrentUserEventHandler(membership_GetRolesForCurrentUserCompleted);
            membership.IsCurrentUserInRoleCompleted += new Infrastructure.Security.IsCurrentUserInRoleEventHandler(membership_IsCurrentUserInRoleCompleted);
        }

        void membership_IsCurrentUserInRoleCompleted(bool UserInRole)
        {
            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.UserInRoleEvent>().Publish(this.lastUserInRole); 
        }

#if !SILVERLIGHT
        void membership_GetRolesForCurrentUserCompleted(string[] Roles)
#else
        void membership_GetRolesForCurrentUserCompleted(System.Collections.ObjectModel.ObservableCollection<string> Roles)
#endif
        {
            this.userRoles = Roles;

            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.UserRolesEvent>().Publish(Roles);
        }

        void authentication_IsLoggedInCompleted(bool IsLoggedIn)
        {
            this.isLoggedIn = IsLoggedIn;

            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.LoggedInEvent>().Publish(IsLoggedIn);     
        }

        void authentication_ValidUserCompleted(bool ValidUser)
        {
            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.ValidUserEvent>().Publish(ValidUser);
        }

        void authentication_LogoutCompleted()
        {
            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.LoggedOutEvent>().Publish(null);
        }

        void authentication_LoginCompleted(bool Login)
        {
            if (Login)
            {
                GetRolesForCurrentUser();
            }

            this.eventAggregator.GetEvent<BlueMarble.Genesis.Infrastructure.Events.Security.LoggedInEvent>().Publish(Login);            
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null) Handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region IAuthenticationViewModelViewModel Members

        public void Login(string Username, string Password)
        {
            this.username = Username;

            authentication.Login(Username, Password);
        }

        public void Logout()
        {
            username = string.Empty;
            lastVerifiedUsername = string.Empty;
            isLoggedIn = false;
            lastUserInRole = string.Empty;
            userRoles = null;

            authentication.Logout();
        }

        public void IsLoggedIn()
        {
            isLoggedIn = false;

            authentication.IsLoggedIn();
        }

        public void ValidateUser(string Username, string Password)
        {
            lastVerifiedUsername = Username;

            authentication.ValidateUser(Username, Password);
        }

        public void GetRolesForCurrentUser()
        {
            userRoles = null;

            membership.GetRolesForCurrentUser();
        }

        public void IsUserInRole(string RoleName)
        {
            lastUserInRole = RoleName;

            membership.IsCurrentUserInRole(RoleName);
        }

        #endregion
    }
}
